package com.congee02.dbservlet.framework.jdbc;

import java.io.InputStream;
import java.sql.*;
import java.util.List;

/**
 * 创建连接，执行
 * 一个简单的 JdbcTemplate 模板封装
 */
public class JdbcTemplate {

    /**
     * 连接对象由 {@link JdbcConnectionTemplate} 维护
     */
    private JdbcConnectionTemplate connectionTemplate;

    private boolean shutdown = false;

    /**
     *
     * 构造器包可见，
     * 包外从
     * {@link JdbcTemplateFactory#getJdbcTemplateFromPropertiesFile(String)}
     * 或者
     * {@link JdbcTemplateFactory#getJdbcTemplateFromPropertiesStream(InputStream)}
     * 读取 Properties 来获取 JdbcTemplate
     *
     */
    JdbcTemplate(String name, String driverClassName, String url, String username, String password, String coreSize, String maxSize) {
        connectionTemplate = new JdbcConnectionTemplate(name, driverClassName, url, username, password, coreSize, maxSize);
    }

    public PreparedStatement createPreparedStatement(String sql, int autoGeneratedKeys, Object... args) throws SQLException {
        if (isShutdown()) {
            throw new IllegalStateException("数据库已经关闭");
        }
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            checkConnectivity();
            while ((connection = connectionTemplate.getConnection()) == null) {
                checkConnectivity();
            }
            statement = connection.prepareStatement(sql, autoGeneratedKeys);
            int argIndex = 1;
            for (Object arg : args) {
                statement.setObject(argIndex ++, arg);
            }
        } finally {
            if (connectionTemplate != null && connection != null) {
                connectionTemplate.releaseConnection(connection);
            }
        }
        return statement;
    }

    public PreparedStatement createPreparedStatement(String sql, Object... args) throws SQLException {
        return createPreparedStatement(sql, Statement.RETURN_GENERATED_KEYS, args);
    }

    /**
     * 无返回值执行 SQL
     */
    public void executeWithoutReturn(String sql) throws SQLException {
        executeWithoutReturn(createPreparedStatement(sql));
    }
    public void executeWithoutReturn(PreparedStatement preparedStatement) throws SQLException {
        try (PreparedStatement statement = preparedStatement) {
            statement.execute();
        }
    }

    /**
     * 使用 SQL 查询
     */
    public ResultSet executeQuery(String sql) throws SQLException {
        return executeQuery(createPreparedStatement(sql));
    }
    public ResultSet executeQuery(PreparedStatement preparedStatement) throws SQLException {
        ResultSet result = null;
        result = preparedStatement.executeQuery();
        return result;
    }

    /**
     * 使用 SQL 增加、删除、更新记录，返回影响的行数
     */
    public int executeUpdate(String sql) throws SQLException {
        return executeUpdate(createPreparedStatement(sql));
    }
    public int executeUpdate(PreparedStatement preparedStatement) throws SQLException {
        int num;
        try (PreparedStatement statement = preparedStatement) {
            num = statement.executeUpdate();
        }
        return num;
    }

    public int[] executeBatch(String... sqlStatements) throws SQLException {
        int[] result;
        try (PreparedStatement statement = createPreparedStatement("");) {
            for (String sql : sqlStatements) {
                statement.addBatch(sql);
            }
            result = statement.executeBatch();
        }
        return result;
    }

    public int[] executeBatch(List<String> sqlStatements) throws SQLException {
        int[] result = null;
        try (PreparedStatement statement = createPreparedStatement("");) {
            for (String sql : sqlStatements) {
                statement.addBatch(sql);
            }
            result = statement.executeBatch();
        }
        return result;
    }

    /**
     * 回收连接资源
     */
    public void shutDown() throws SQLException {
        if (! isShutdown()) {
            connectionTemplate.shutDown();
            connectionTemplate = null;
            shutdown = true;
        }
    }

    // x. 简便方法
    public boolean isShutdown() {
        return shutdown;
    }
    private void checkConnectivity() {
        if (isShutdown()) {
            throw new IllegalStateException("数据库已经关闭");
        }
    }

}
